<template>
    <view class="qly-select" @tap="openModel" :class="{
		'qly-select--border':border,
		'qly-select__disabled':disabled
	}">
        <slot>
            <view class="left">
                <text class="qly-select-label" v-if="isNotEmpty(value)">{{ showLabel }}</text>
                <text class="qly-select-placeholder" v-else>{{ placeholder }}</text>
            </view>
            <template v-if="showIcons">
                <view v-if="isNotEmpty(value) && clearable && !disabled" @tap.stop="clear" class="clear">
                    <uni-icons type="clear" :size="rightIconSize" :color="rightIconColor"/>
                </view>
                <view v-else>
                    <uni-icons type="right" :size="rightIconSize" :color="rightIconColor"/>
                </view>
            </template>
        </slot>
    </view>
    
    <qly-select-picker ref="popupRef" :options="options" :customProps="customProps" :multiple="multiple"
                       :search="search" :title="title" :height="height" :cancelText="cancelText"
                       :confirmText="confirmText" :selectColor="selectColor" :cancelColor="cancelColor"
                       :confirmColor="confirmColor" @confirm="confirm" @cancel="emits('cancel')"/>
</template>

<script setup>
import config from '@/qly/ext/select'
import {isNotEmpty} from '@/qly/verificate'

const emits = defineEmits(['update:modelValue', 'confirm', 'cancel', 'clear'])

const props = defineProps({
    modelValue: {type: [String, Number, Array], default: null},
    apiObj: {
        type: Function, default: () => {
        }
    },
    data: {type: Array, default: null},
    params: {type: Object, default: () => ({})},
    defaultValue: {type: Boolean, default: false},
    closeAutoLoad: {type: Boolean, default: false},
    customProps: {type: Object, default: config.props},
    placeholder: {type: String, default: '请选择'},
    multiple: {type: Boolean, default: false},
    disabled: {type: Boolean, default: false},
    clearable: {type: Boolean, default: true},
    search: {type: Boolean, default: true},
    border: {type: Boolean, default: true},
    title: {type: String, default: ''},
    height: {
        type: [Number, String],
        default: '800rpx'
    },
    cancelText: {type: String, default: '取消'},
    confirmText: {type: String, default: '确认'},
    selectColor: {type: String, default: "#409EFF"},
    cancelColor: {type: String, default: "#909399"},
    confirmColor: {type: String, default: "#3c9cff"},
    rightIconSize: {type: Number, default: 22},
    rightIconColor: {type: String, default: "#c0c4cc"},
    showIcons: {type: Boolean, default: true},
})

const value = useModel(props, 'modelValue')
const popupRef = ref()
const loading = ref(false)
const options = ref([])

const showLabel = computed(() => {
    if (props.multiple) {
        if (isNotEmpty(options.value)) {
            let labelList = []
            options.value.forEach(item => {
                if (value.value.indexOf(getValueKeyValue(item)) !== -1) {
                    labelList.push(getLabelKeyValue(item))
                }
            })
            if (isNotEmpty(labelList)) {
                return labelList.join(',')
            }
        }
    } else {
        for (let item of options.value) {
            if (value.value === getValueKeyValue(item)) {
                return getLabelKeyValue(item)
            }
        }
    }
    return null
})

onMounted(() => {
    if (props.closeAutoLoad) {
        return
    }
    if (props.data) {
        options.value = props.data
    } else {
        //修改为同步调用
        getRemoteData()
    }
})

// 监听params
watch(() => props.params, (newVal, oldVal) => {
    if (JSON.stringify(newVal) !== JSON.stringify(oldVal)) {
        getRemoteData(newVal)
    }
}, {deep: true})

// 监听data
watch(() => props.data, (newVal) => {
    options.value = newVal || []
}, {deep: true})

// 获取数据
async function getRemoteData(params) {
    loading.value = true;
    if (!params) {
        params = props.params;
    }
    let res;
    if (props.apiObj) {
        res = await props.apiObj(params);
    } else {
        res = await config.dictApiObj(params);
    }
    const response = config.parseData(res);
    if (response.success) {
        options.value = response.data || [];
        if (props.defaultValue && isNotEmpty(response.data)) {
            value.value = getValueKeyValue(response.data[0])
        }
    }
    loading.value = false;
}

// 打开选择弹窗
function openModel() {
    if (props.disabled) {
        return;
    }
    popupRef.value.open(value.value)
}

// 确认
function confirm(val) {
    value.value = val
    popupRef.value.close()
    emits('confirm', qly.tool.deepCopy(val))
}

// 获取label
function getLabelKeyValue(item) {
    try {
        return item[props.customProps.label] ?? ''
    }catch (e){
        return  ''
    }
}

// 获取value
function getValueKeyValue(item) {
    try {
        return item[props.customProps.value]
    }catch (e){
        return ''
    }
}

// 清除
function clear() {
    let newValue
    if (props.multiple) {
        newValue = []
    } else {
        newValue = null
    }
    value.value = newValue
    emits('clear')
    emits('confirm', newValue)
}

// 清空选项
function clearOptions() {
    options.value = []
}

defineExpose({
    openModel,
    getRemoteData,
    clear,
    clearOptions
})
</script>

<style lang="scss" scoped>
.qly-select{
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 10rpx 0;
    color: #333;
    width: 100%;
    .left{
        .qly-select-placeholder{
            color: rgb(137, 137, 137);
        }
    }
}
.qly-select--border {
    box-sizing: border-box;
    border-radius: 4px;
    border: 1px solid #e5e5e5;
    padding-left: 8px;
    padding-right: 3px;
}
</style>
